package com.yc.vote.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import java.util.logging.Handler;

public class MyBatisHelper {


    private static SqlSessionFactory sqlSessionFactory;

    static {
        String resource = "mybatis.xml";
        // 读取配置文件
//        InputStream inputStream = null;
        try(InputStream inputStream = Resources.getResourceAsStream(resource);){
            // 构建会话工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            throw new RuntimeException("MyBatis 初始化失败！", e);
        }

    }
    public static SqlSession opensSession() {
        // 通过会话工厂创建会话
        return sqlSessionFactory.openSession();
    }

    // 执行 mybatis 数据库操作
    public static void exec(Handler handler) {
        SqlSession session = MyBatisHelper.opensSession();
        try{
            // handler 用于执行用户的业务代码
            handler.handle(session);
            // 正常情况下提交
            session.commit();
        } catch (Exception e){
            // 异常回滚
            session.rollback();
            throw new RuntimeException("数据库操作错误", e);
        } finally {
            // 关闭会话
            session.close();
        }
    }

    // 用查询的模板方法
    public static <E> E query(Queryer queryer){
        SqlSession session = MyBatisHelper.opensSession();
        try {
            // handler 用于执行用户的业务代码
            return (E) queryer.query(session);
        } catch (Exception e){
            throw new RuntimeException("数据库操作执行错误", e);
        } finally {
            // 关闭会话
            session.close();
        }

    }

    // 单参数接口，就是函数接口，可以写lambdo 表达式
    public static interface Handler{
        void handle(SqlSession session);
    }

    public static interface Queryer<E>{
        E query( SqlSession session);
    }

}
